package com.unionpay.async;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.Date;

import org.apache.ibatis.session.SqlSession;

import com.unionpay.db.Mybaties;
import com.unionpay.rpc.Data;
import com.unionpay.rpc.DataObj;
import com.unionpay.rpc.Rpc;
import com.unionpay.rpc.RpcMethod;
import com.unionpay.util.StrUtil;

/**
 * 异步队列任务
 * 
 * @author liuzy
 * @since 2016年4月29日
 */
public class AsyncTask {
	// 请求RPC次数
	private static ThreadLocal<Integer> RPC_COUNT = new ThreadLocal<Integer>();
	// 请求间隔时间
	private static final int REQ_INTERVAL = 5000;

	private String transactionid;
	private String sql;
	private ArrayList<String> params = new ArrayList<String>();

	public AsyncTask(String sql, String transactionid) {
		this.sql = sql;
		this.transactionid = transactionid;
	}

	public AsyncTask(String sql, String[] params) {
		this.sql = sql;
		for (String param : params) {
			this.params.add(param);
		}
	}

	public void execute() {
		if (transactionid != null) {
			RPC_COUNT.set(6);
			try {
				RpcMethod method = new RpcMethod(Rpc.ETH_GETTRANSACTIONBYHASH);
				method.addParams(transactionid);
				while (true) {
					if (RPC_COUNT.get() > 0) {
						// 先休息一下
						Thread.sleep(REQ_INTERVAL);
						// 请求一次
						RPC_COUNT.set(RPC_COUNT.get() - 1);
						Data data = Rpc.request(method);
						if (data instanceof DataObj) {
							DataObj.Trade trade = ((DataObj) data).getResult();
							String blockHash = trade.getBlockHash();
							params.clear();
							params.add(transactionid);
							params.add(blockHash);
							params.add(trade.getBlockNumber());
							params.add(trade.getFrom());
							params.add(trade.getGas());
							params.add(trade.getGasPrice());
							params.add(trade.getHash());
							params.add(trade.getInput());
							params.add(trade.getNonce());
							params.add(trade.getTo());
							params.add(trade.getTransactionIndex());
							params.add(trade.getValue());
							params.add(StrUtil.getDate(new Date()));
							if (blockHash != null && !blockHash.equals("0x0000000000000000000000000000000000000000000000000000000000000000")) {
								break;
							}
						}
					} else {
						break;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		SqlSession session = null;
		Connection conn = null;
		PreparedStatement stmt = null;
		try {
			session = Mybaties.openSession();
			conn = session.getConnection();
			stmt = conn.prepareStatement(sql);
			int i = 1;
			for (String param : params) {
				stmt.setString(i, param);
				i++;
			}
			stmt.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (stmt != null) {
					stmt.close();
				}
				if (conn != null) {
					conn.close();
				}
				if (session != null) {
					session.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}

}
